package main

import (
	"github.com/gin-gonic/gin"
	"go-admin-official/controllers"
	"go-admin-official/guard"
	"go-admin-official/modules/auth"
	"go-admin-official/modules/logger"
	"net/http"
	"strings"
)

var staticPages = map[string]string{
	"/download": "download",
	"/solution": "solution",
	"/login":    "login",
	"/register": "register",
	"/en/":      "en_index",
	"/en/index": "en_index",
	"/docs/test": "docs",
}

var authStaticPages = map[string]string{
	"/user/center":     "user_center",
	"/user/buy/videos": "user_buy_video",
	"/user/charge":     "user_charge",
	"/user/invite":     "user_invite",
	"/user/checkin":    "user_check_in",
	"/user/setting":    "user_setting",
	"/user/workorder":  "user_work_order",
	"/user/invoice":    "user_invoice",
	"/user/coupons":    "user_coupons",
}

func buildRouters(r *gin.Engine) *gin.Engine {

	r.NoRoute(func(c *gin.Context) {

		if c.Request.Method == "OPTIONS" {
			SetCrossOrigin(c)
			c.String(http.StatusOK, "ok")
			return
		}

		c.JSON(http.StatusNotFound, gin.H{
			"code": 404,
			"msg":  "not found",
		})
		return
	})

	r.NoMethod(func(c *gin.Context) {

		if c.Request.Method == "OPTIONS" {
			SetCrossOrigin(c)
			c.String(http.StatusOK, "ok")
			return
		}

		c.JSON(http.StatusNotFound, gin.H{
			"code": 404,
			"msg":  "not found",
		})
		return
	})

	router := r.Group("/", errorHandler)

	for r, p := range staticPages {
		router.GET(r, controllers.Page(p))
	}

	apiRoute := router.Group("/api", SetCrossOrigin)

	// 用户注册
	router.POST("/signup", guard.Pv(guard.SignUp()), controllers.SignUp)
	// 用户登录
	router.POST("/signin", guard.Pv(guard.SignIn()), controllers.SignIn)
	apiRoute.POST("/signin", guard.Pv(guard.SignIn()), controllers.ApiSignIn)

	// 检查邮箱/电话/用户名唯一性
	router.POST("/check/uniqueness", guard.Pv(guard.Unique()), controllers.Unique)

	router.GET("/user-agreement", controllers.UserAgreement)

	router.GET("/", controllers.Index)
	router.GET("/index", controllers.Index)

	router.GET("/donation", controllers.Donation)

	apiRoute.GET("/plugin/list", guard.Pv(guard.Plugins()), controllers.ApiPlugins)

	apiRoute.GET("/theme/list", guard.Pv(guard.Plugins()), controllers.ApiThemes)

	// TODO: 第三方绑定

	authRoute := router.Group("/", func(ctx *gin.Context) {
		_, ok := auth.Filter(ctx)

		if !ok {
			ctx.Redirect(http.StatusMovedPermanently, "/login")
			ctx.Abort()
			return
		}
	})

	for r, p := range authStaticPages {
		authRoute.GET(r, controllers.AuthPage(p))
	}

	authRoute.GET("/user/buy/plugins", guard.Pv(guard.PluginsBuy()), controllers.PluginsBuy)
	authRoute.GET("/user/buy/themes", guard.Pv(guard.PluginsBuy()), controllers.ThemesBuy)

	authJSONRoute := router.Group("/", func(ctx *gin.Context) {
		_, ok := auth.Filter(ctx)

		if !ok {
			ctx.JSON(http.StatusUnauthorized, gin.H{"code": 401, "msg": "please login first"})
			ctx.Abort()
			return
		}
	})
	authJSONapiRoute := apiRoute.Group("/", func(ctx *gin.Context) {
		_, ok := auth.Filter(ctx)

		if !ok {
			ctx.JSON(http.StatusUnauthorized, gin.H{"code": 401, "msg": "please login first"})
			ctx.Abort()
			return
		}
	})

	// 退出登录
	authJSONRoute.POST("/logout", controllers.Logout)

	// 用户个人页面
	//authRoute.GET("/user/center")

	// 主题列表
	router.GET("/themes", guard.Pv(guard.Themes()), controllers.Themes)
	// 主题详情
	router.GET("/themes/detail/:uuid", controllers.ThemeDetail)

	// 插件列表
	router.GET("/plugins", guard.Pv(guard.Plugins()), controllers.Plugins)
	// 插件详情
	router.GET("/plugins/detail/:uuid", controllers.PluginDetail)
	// 获取付费插件下载链接
	authJSONapiRoute.POST("/plugin/download", guard.Pv(guard.PluginsDownload()), controllers.PluginDownload)
	// 购买插件
	authJSONRoute.POST("/product/buy", guard.Pv(guard.CreateOrder()), controllers.CreateProductBuyOrder)
	authJSONapiRoute.POST("/product/buy", guard.Pv(guard.CreateOrder()), controllers.CreateProductBuyOrder)
	authRoute.GET("/alipay/qrcode", controllers.Qrcode)
	// 支付回调
	apiRoute.Any("/pay/callback", controllers.PayCallback)
	apiRoute.Any("/pay/callback/alipay", controllers.AliPayCallback)

	// 轮询购买支付结果信息
	authJSONRoute.POST("/product/buy/result", controllers.PayResult)

	// 评论插件
	// 点赞插件

	// 需求墙壁

	return r
}

func errorHandler(ctx *gin.Context) {
	defer func() {
		if err := recover(); err != nil {
			logger.Error(err)

			if strings.Contains(ctx.GetHeader("Accept"), "json") {
				ctx.JSON(http.StatusOK, gin.H{
					"code": http.StatusInternalServerError,
					"msg":  "服务器错误",
				})
			} else {
				ctx.Redirect(http.StatusMovedPermanently, "/")
			}
		}
	}()
}

func SetCrossOrigin(c *gin.Context) {
	c.Header("Access-Control-Allow-Origin", "*")
	c.Header("Access-Control-Allow-Credentials", "true")
	c.Header("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, OPTIONS")
	c.Header("Access-Control-Allow-Headers", "Authorization, Origin, Content-Type, Cookie, Accept, X-Requested-With, Location, x-mytest-token")
	c.Header("Access-Control-Max-Age", "60")
}
